package org.projectwithoutname.ui.wizard.pages;

import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.projectwithoutname.commons.Commons;
import org.projectwithoutname.ui.wizard.pages.composite.ImageComposite;

public class ImagePage extends WizardPage{
	private ImageComposite container;
	private ImageData imageData;
	private Rectangle rectangle;
	private boolean in = false, up = true, cursorNW = false, cursorSW = false, cursorNE = false, cursorSE = false;
	private boolean hold = true, risizing = false;
	private Display display;
	private int dx, dy, ex, ey, width, height, x, y;
	
	public ImagePage(String pageName, ImageData imageData) {
		super(pageName);
		setTitle(pageName);
		setDescription("Cut the image");
		setPageComplete(true);
		this.imageData = imageData;
	}

	@Override
	public void createControl(final Composite parent){
		display = parent.getDisplay();
		container = new ImageComposite(parent,SWT.None, imageData);

		container.getImageLabel().addMouseMoveListener(new MouseMoveListener() {
			
			@Override
			public void mouseMove(MouseEvent e) {
				if (hold){
					hold = false;
					if (!risizing){
						if(!(cursorNE || cursorNW || cursorSE || cursorSW)){
							rectangle = container.getRectangle();
							width = rectangle.width;
							height = rectangle.height;
							x = rectangle.x;
							y = rectangle.y;
						}
						if ((e.x >= rectangle.x - 2) && (e.x <= rectangle.width + 2) && (e.y >= rectangle.y - 2) && (e.y <= rectangle.height + 2)){
							Cursor cursor = null;
							if ((e.x > rectangle.x + 2) && (e.x < rectangle.width - 2) && (e.y > rectangle.y + 2) && (e.y < rectangle.height- 2)){
								cursor = new Cursor(display, SWT.CURSOR_HAND);
								container.getImageLabel().setCursor(cursor);
								cursorNW = false; cursorSW = false; cursorNE = false; cursorSE = false;
							}
							else{
								if (e.x < rectangle.x + 2){
									if (e.y < rectangle.y + 2){
										cursor = new Cursor(display, SWT.CURSOR_SIZENW);
										cursorNW = true; cursorSW = false; cursorNE = false; cursorSE = false;
									}else if (e.y >= rectangle.height - 2){
										cursor = new Cursor(display, SWT.CURSOR_SIZESW);
										cursorNW = false; cursorSW = true; cursorNE = false; cursorSE = false;
									}
								}
								else if (e.x >= rectangle.width - 2){
									if (e.y < rectangle.y + 2){
										cursor = new Cursor(display, SWT.CURSOR_SIZENE);
										cursorNW = false; cursorSW = false; cursorNE = true; cursorSE = false;
									}else if (e.y >= rectangle.height - 2){
										cursor = new Cursor(display, SWT.CURSOR_SIZESE);
										cursorNW = false; cursorSW = false; cursorNE = false; cursorSE = true;
									}
								}
								container.getImageLabel().setCursor(cursor);
							}
						}
						else{
							Cursor handCursor = new Cursor(display, SWT.CURSOR_ARROW);
							container.getImageLabel().setCursor(handCursor);
						}
					}
					hold = true;
					if(in && !up){
						
						
						if (!(cursorNE || cursorNW || cursorSE || cursorSW)){
							hold = false;
							int diffX = e.x - rectangle.x - dx, diffY = e.y - rectangle.y - dy;
							
							rectangle.x += diffX;
							rectangle.width += diffX;
							rectangle.y += diffY;
							rectangle.height += diffY;
							container.setRectangle(rectangle);
							hold = true;
						}
						else risizeRectangle(e);
					}
					
				}
			}
		});
		
		container.getImageLabel().addMouseListener(new MouseListener() {
			
			@Override
			public void mouseUp(MouseEvent e) {
				up = true;
				dx = 0;
				dy = 0;
			}
			
			@Override
			public void mouseDown(MouseEvent e) {
				up = false;
				if ((e.x >= rectangle.x - 2) && (e.x <= rectangle.width + 2) && (e.y >= rectangle.y - 2) && (e.y <= rectangle.height + 2)){
					in = true;
					if ((e.x >= rectangle.x + 2) && (e.x <= rectangle.width - 2) && (e.y >= rectangle.y + 2) && (e.y <= rectangle.height - 2)){
						dx = e.x - rectangle.x;
						dy = e.y - rectangle.y;
					}
					else
						if (hold){
							ex = e.x;
							ey = e.y;
						}
				}
				else
					in = false;
				
			}
			
			@Override
			public void mouseDoubleClick(MouseEvent e) {
			}
		});
		setControl(container);

	}
	
	private void risizeRectangle(MouseEvent e){
		risizing = true;
		int diffX = e.x - ex;
		int diffY = e.y - ey;

		Rectangle auxRectangle = new Rectangle(0, 0, 0, 0);
		if (hold && (positeValue(diffX) > 16 || positeValue(diffY) > 5)){
			int factor = gt(diffX, diffY);
			
			if (cursorNW){
				hold = false;
				auxRectangle.x = rectangle.x + factor*16;
				auxRectangle.y = rectangle.y + factor*5;
				auxRectangle.width = width;
				auxRectangle.height = height;
				int checkX = auxRectangle.width - auxRectangle.x;
				int checkY = auxRectangle.height - auxRectangle.y;
				
				if (!((checkX < Commons.SELECTION_WIDTH) || (checkY < Commons.SELECTION_HEIGHT))){
//					auxRectangle.width = auxRectangle.x + Commons.SELECTION_WIDTH + 16;
//					auxRectangle.height = auxRectangle.y + Commons.SELECTION_HEIGHT + 5;
					container.setRectangle(auxRectangle);
					
				}
				
//				container.setRectangle(auxRectangle);
				hold = true;
			}
			else if (cursorSW){
				hold = false;
				auxRectangle.x = rectangle.x - factor*16;
				auxRectangle.height = rectangle.height + factor*5;
				auxRectangle.width = width; //rectangle.width - factor*16;
				auxRectangle.y = y;//rectangle.y + factor*5;
				
				int checkX = auxRectangle.width - auxRectangle.x;
				int checkY = auxRectangle.height - auxRectangle.y;
				if (!((checkX < Commons.SELECTION_WIDTH) || (checkY < Commons.SELECTION_HEIGHT))){
//					auxRectangle.width = auxRectangle.x + Commons.SELECTION_WIDTH + 16;
//					auxRectangle.y = auxRectangle.height - Commons.SELECTION_HEIGHT - 5;
					container.setRectangle(auxRectangle);
				}
//				container.setRectangle(auxRectangle);
				hold = true;
			}
			else if (cursorSE){
				hold = false;
				auxRectangle.width = rectangle.width + factor*16;
				auxRectangle.height = rectangle.height + factor*5;
				auxRectangle.y = rectangle.y;
				auxRectangle.x = rectangle.x;
				
				int checkX = auxRectangle.width - auxRectangle.x;
				int checkY = auxRectangle.height - auxRectangle.y;
				if (!((checkX < Commons.SELECTION_WIDTH) || (checkY < Commons.SELECTION_HEIGHT))){
//					auxRectangle.width = auxRectangle.x + Commons.SELECTION_WIDTH + 16;
//					auxRectangle.y = auxRectangle.height - Commons.SELECTION_HEIGHT - 5;
					container.setRectangle(auxRectangle);
				}
//				container.setRectangle(auxRectangle);
				hold = true;
			}
			else if (cursorNE){
				hold = false;
				auxRectangle.width = rectangle.width + factor*16;
				auxRectangle.y = rectangle.y - factor*5;
				auxRectangle.x = rectangle.x;
				auxRectangle.height = rectangle.height;
				
				int checkX = auxRectangle.width - auxRectangle.x;
				int checkY = auxRectangle.height - auxRectangle.y;
				if (!((checkX < Commons.SELECTION_WIDTH) || (checkY < Commons.SELECTION_HEIGHT))){
//					auxRectangle.width = auxRectangle.x + Commons.SELECTION_WIDTH + 16;
//					auxRectangle.y = auxRectangle.height - Commons.SELECTION_HEIGHT - 5;
					container.setRectangle(auxRectangle);
				}
//				container.setRectangle(auxRectangle);
				hold = true;
			}
		}
		risizing = false;
	}
	
	/**
	 * return grater than between the factor x and factor y
	 * @param dx 
	 * @param dy   
	 * @return grater factor
	 */
	private int gt(int dx, int dy){
		int fx = dx/16;
		int fy = dy/5;
		return fx >= fy ? fx : fy;
	}
	
	private int positeValue(int value){
		return value < 0? value*(-1): value;
	}
	
	public Rectangle getRectangle(){
		return rectangle;
	}
	
	public ImageData getImageData(){
		return container.getImageLabel().getImage().getImageData();
	}
}
